import { Component, Vue, Emit, Watch } from 'vue-property-decorator';
import { superFun, limiting } from '@/utils/Annotate'
import { set, get, cloneDeep } from 'lodash'
/**
 * 这是一个弹窗mixin类
 * 提供了一些弹窗显示隐藏、设置和获取弹窗数据的方法
 * 通常在弹窗父容器中通过ref找到弹窗对象，调用具体方法来实现相关交互操作
 * 这样写是为了避免在父容器中定义大量变量，不利于快速开发和维护
 */
@Component({
})
export class mixinViewDialog extends Vue {
    /**
     * 定义closeDialog事件
     * 一般在弹窗关闭后触发
     * 在父容器中组件需要如下设置 @closeDialog="onCloseDialog"
     *
     * @memberof mixinViewDialog
     */
    @Emit('closeDialog') closeDialog() {
    }

    /**
     * 用于控制弹窗是否显示
     * 弹窗组件需要如下设置 :visible.sync="isShow"
     * 父容器通过setHidden方法来控制
     * @type {boolean}
     * @memberof mixinViewDialog
     */
    isShow: boolean = false;
    /**
     * 设置弹窗是否隐藏
     * 此方法提供给父组件调用
     * @param {boolean} v
     * @memberof mixinViewDialog
     */
    setHidden(v: boolean) {
        this.isShow = !v;
    }

    /**
     * 弹窗数据
     * 父容器通过setValue/getValue 设置/获取
     * 默认值为 -1
     * 每次弹窗关闭时父容器会通过mixinDialogParent中的方法将其重置为-1
     * @type {*}
     * @memberof mixinViewDialog
     */
    infoData: any = -1;
    /**
     * 监听弹窗数据变化
     *
     * @param {*} data 具体数据
     * @memberof mixinViewDialog
     */
    @Watch("infoData")
    updateinfoData(data: any) {
        const me = this as any;
        // 当数据变化时会触发init方法
        // 可以在这个方法中写具体的交互逻辑
        if (me.isShow) {
            // 视图绘制完执行，避免无法重置数据
            me.$nextTick(() => {
                if (![-1, 0].includes(data)) {
                    // 编辑时触发
                    // 内部使用
                    me.beforEditInit && me.beforEditInit(data);
                    me.editInit && me.editInit(data);
                } else {
                    // 新增时触发
                    // 内部使用
                    me.beforAddInit && me.beforAddInit();
                    me.addInit && me.addInit();
                }
            })
        }
    }

    /**
     * 设值值
     *
     * @param {string} key 字段名称
     * @param {*} data 字段值
     * @memberof mixinViewDialog
     */
    setValue(key: string, data: any) {
        set(this, key, cloneDeep(data));
    }

    /**
    * 获取值
    *
    * @param {string} key 字段名称
    * @memberof mixinViewDialog
    */
    getValue(key: string) {
        return get(this, key);
    }


    /**
     * 关闭弹窗
     * 使用时在dialog中配置@close="onDialogClose"
     * 取消按钮中配置@click="onDialogClose"
     * 点击取消按钮时，取消按钮@click="onDialogClose"先触发此方法,然后dialog的@close="onDialogClose"会二次触发此方法
     * 点击dialog的关闭按钮时,dialog的@close="onDialogClose"会触发此方法
     * 所以这里通过limiting注解做限流处理
     *
     * @memberof mixinViewDialog
     */
    @superFun()
    @limiting(300)
    onDialogClose() {
        const me = this as any;
        // 检查是否有closeBefore方法，如果有就执行
        me.closeBefore && me.closeBefore();
        // 触发事件
        me.closeDialog(me.$vnode.data.ref);
    }
}
